/*
 * ------------------------------------------------------------------
 * Copyright © 2017 Hangzhou DtDream Technology Co.,Lt d. All rights reserved.
 * ------------------------------------------------------------------
 *       Product:
 *   Module Name:
 *  Date Created: 2023/7/11
 *   Description:
 * ------------------------------------------------------------------
 * Modification History
 * DATE            Name           Description
 * ------------------------------------------------------------------
 * 2023/7/11    小谷 g2038          created
 * ------------------------------------------------------------------
 */
package com.gujh.security.authentication.sms;

import cn.hutool.core.util.StrUtil;
import com.gujh.security.util.CacheUtil;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;

public class SmsAuthenticationProvider implements AuthenticationProvider {

    private final SecurityUserService securityUserService;

    public SmsAuthenticationProvider(SecurityUserService securityUserService) {
        this.securityUserService = securityUserService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        SmsAuthenticationToken authenticationToken = (SmsAuthenticationToken) authentication;
        Object principal = authentication.getPrincipal();// 获取凭证也就是用户的手机号
        String phone = "";
        if (principal instanceof String) {
            phone = (String) principal;
        }
        String inputCode = (String) authentication.getCredentials(); // 获取输入的验证码
        // 1. 检验Redis手机号的验证码
        String redisCode = CacheUtil.getCodeByPhone(phone);
        if (StrUtil.isEmpty(redisCode)) {
            throw new BadCredentialsException("验证码已经过期或尚未发送，请重新发送验证码");
        }
        if (!inputCode.equals(redisCode)) {
            throw new BadCredentialsException("输入的验证码不正确，请重新输入");
        }
        // 2. 根据手机号查询用户信息
        UserDetails userDetails = securityUserService.loadUserByPhone(phone);
        if (userDetails == null) {
            throw new InternalAuthenticationServiceException("phone用户不存在，请注册");
        }
        // 3. 创建已认证对象
        SmsAuthenticationToken auth = SmsAuthenticationToken.authenticated(principal, userDetails, userDetails.getAuthorities());
        auth.setDetails(authenticationToken.getDetails());
        return auth;
    }


    @Override
    public boolean supports(Class<?> aClass) {
        // 当 SmsAuthenticationToken 认证时，匹配该类
        return SmsAuthenticationToken.class.isAssignableFrom(aClass);
    }
}

